package com.dmg.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * 自定义 MybatisAutoConfiguration中的
 * SqlSessionFactory SqlSessionTemplate 配置
 * 读取mapper.xml里面的内容
 * 如果不加这个类，那么动态数据源的determineCurrentLookupKey()方法不会生效
 * 项目启动也会报错
 */
@Slf4j
@Configuration
//读取mapper接口类的路径
@MapperScan(value = {"com.dmg.dao"},sqlSessionTemplateRef = "myDynamicSqlSessionTemplate")
public class MyAutoConfiguration {


    /**
     * 把sqlSessionFactory 注入到ioc容器
     * 这里的dataSource 是从ioc容器拿的数据源
     * 在@Bean里面指定bean的名称 防止出现重复 结合@Qualifier 就能找到对应的bean信息
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory myDynamicSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置数据源 到sqlSessionFactoryBean中
        sqlSessionFactoryBean.setDataSource(dataSource);
        //设置扫描mapper.xml的路径
        //对应application.properties文件中的 mybatis.mapper-locations=classpath:mappers/*.xml
        PathMatchingResourcePatternResolver path = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(path.getResources("classpath:mappers/*.xml"));
        //解决mybatis 别名不生效问题
        sqlSessionFactoryBean.setVfs(SpringBootVFS.class);
        return sqlSessionFactoryBean.getObject();
    }

    /**
     * 管理数据库会话sqlSession的生命周期 并且是线程安全的 可以被多个dao 共享
     * sqlSession 用于执行sql语句 提交或者回滚事务
     * @Qualifier 注解根据bean的名字找到对应的bean信息
     * @param sqlSessionFactory 上面的方法注入到ioc容器中的bean
     * @return
     */
    @Bean
    public SqlSessionTemplate myDynamicSqlSessionTemplate(@Qualifier("myDynamicSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        //通过sqlSessionFactory 创建sqlSession
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}
